package org.boulderfoodrescue.webapp.server.users;

import java.util.List;
import java.util.logging.Logger;

import org.boulderfoodrescue.webapp.client.rpc.UserAccountsService;
import org.boulderfoodrescue.webapp.shared.UserAccount;
import org.boulderfoodrescue.webapp.shared.UserAccountDetails;
import org.boulderfoodrescue.webapp.shared.UserAccountDetails.AccessLevel;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

@SuppressWarnings("serial")
public class UserAccountsServiceImpl extends RemoteServiceServlet implements UserAccountsService{
	private static final Logger log = Logger.getLogger(UserAccountsServiceImpl.class.getName());

	@Override
	public Long saveProfileData(UserAccount user) {
		UserService userService = UserServiceFactory.getUserService();
		User person = userService.getCurrentUser();
		if(person == null){
			log.warning("User is not logged in. Cannot execute saveProfileData() call");
			return null;
		}
		UserAccount userA = UserAccountsDatabase.getUser(person.getEmail());
		if(!person.getEmail().equals(user) && userA.getAccessLevel().compareTo(AccessLevel.Admin) < 0)
		{
			log.warning("User is not updating own account or does not have permision to update other account "+person.getEmail());
			return null;
		}
		Long result;
		UserAccount query = UserAccountsDatabase.getUser(user.getEmail());
		if(query != null){
			UserAccountsDatabase.updateUser(user);
			result = user.getDatabaseKey();
		}
		else {
			result = UserAccountsDatabase.addUser(user);
		}
		return result;
	}

	@Override
	public UserAccount getUser() {
		UserService userService = UserServiceFactory.getUserService();
		User user = userService.getCurrentUser();
		if(user == null){
			log.warning("User is not logged in. Cannot execute getUser() call");
			return null;
		}
		return UserAccountsDatabase.getUser(user.getEmail());
	}
	@Override
	public List<UserAccount> getUsers() {
		List<UserAccount> users;
		UserService userService = UserServiceFactory.getUserService();
		User user = userService.getCurrentUser();
		if(user == null)
			return null;
		UserAccount userA = UserAccountsDatabase.getUser(user.getEmail());
		if(userA.getAccessLevel().compareTo(AccessLevel.Volunteer) < 0)
		{
			log.warning("User does not have authority to get a list of users "+user.getEmail() +" access level="+userA.getAccessLevel());
			return null;
		}
		users = UserAccountsDatabase.getUsers();
		return users;
	}

	@Override
	public boolean removeUser(UserAccount user) {
		UserService userService = UserServiceFactory.getUserService();
		User userS = userService.getCurrentUser();
		if(userS == null){
			log.warning("User is not logged in. Cannot execute getListUsers() call");
			return false;
		}
		UserAccount userA = UserAccountsDatabase.getUser(userS.getEmail());
		if(userA.getAccessLevel().compareTo(AccessLevel.Admin) < 0 && userS.getEmail() != user.getEmail())
		{
			log.warning("User does not have authority to get a list of users "+user.getEmail() +" access level="+userA.getAccessLevel());
			return false;
		}
		UserAccountsDatabase.removeUser(user);
		return true;
	}

	@Override
	public List<UserAccountDetails> getListUsers() {
		UserService userService = UserServiceFactory.getUserService();
		User user = userService.getCurrentUser();
		if(user == null){
			log.warning("User is not logged in. Cannot execute getListUsers() call");
			return null;
		}
		UserAccount userA = UserAccountsDatabase.getUser(user.getEmail());
		if(userA.getAccessLevel().compareTo(AccessLevel.Volunteer) < 0)
		{
			log.warning("User does not have authority to get a list of users "+user.getEmail() +" access level="+userA.getAccessLevel());
			return null;
		}
		return UserAccountsDatabase.getUserAccountDetails();
	}

	@Override
	public boolean removeUser(UserAccountDetails user) {
		UserService userService = UserServiceFactory.getUserService();
		User userS = userService.getCurrentUser();
		if(userS == null){
			log.warning("User is not logged in. Cannot execute getListUsers() call");
			return false;
		}
		UserAccount userA = UserAccountsDatabase.getUser(userS.getEmail());
		if(userA.getAccessLevel().compareTo(AccessLevel.Admin) < 0 && userS.getEmail() != user.getEmail())
		{
			log.warning("User does not have authority to get a list of users "+user.getEmail() +" access level="+userA.getAccessLevel());
			return false;
		}
		UserAccount toRemove = UserAccountsDatabase.getUser(user.getEmail());
		if(toRemove == null)
			return false;
		UserAccountsDatabase.removeUser(toRemove);
		return true;
	}

}
